﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using ComicIsland.Common;
using ComicIsland.Common.Cache;
using System.IO.IsolatedStorage;
using ComicIsland.Common.StorageHelper;
using System.Reflection;
using ComicIsland.Common.Entities.LocalDatabase;

namespace ComicIsland.App.Controls
{
    public partial class ImagePlane : UserControl
    {
        private const double DoubleTapScale = 2;

        public readonly static DependencyProperty ImageProperty = DependencyProperty.RegisterAttached("QImage",
            typeof(LDBComicChapterImage),
            typeof(ImagePlane),
            new PropertyMetadata(null, OnImageChanged));

        private CAsyncImageTask _tmpTask;

        private double _width = 480;

        private double _height = 800;

        public bool Mutexes;

        private double _dscale = 1;

        private Point _oPoint;

        public double DistanceY
        {
            get;
            set;
        }

        public bool IsDragHorizontal
        {
            get;
            set;
        }

        public ComicIsland.Common.Helper.SrnOrientation Orientation
        {
            get;
            set;
        }

        public double ScreenHeight
        {
            get
            {
                return this._height;
            }
            set
            {
                this._height = value;
            }
        }

        public double ScreenWidth
        {
            get
            {
                return this._width;
            }
            set
            {
                this._width = value;
            }
        }

        public double TransfromY { get; set; }

        public ImagePlane()
        {
            InitializeComponent();
        }

        public void DoubleTap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            this.Mutexes = true;
            if (this.transform.ScaleX < 2)
            {
                double num = 2;
                this.RestSx.To = new double?(num);
                this.RestSy.To = (new double?(num));
                this.RestS.Begin();
                this.transform.ScaleY = (num);
                this.transform.ScaleX = (num);
                this.IsDragHorizontal = false;
                return;
            }
            double num1 = 1;
            this.RestSx.To = (new double?(num1));
            this.RestSy.To = (new double?(num1));
            this.RestS.Begin();
            this.transform.ScaleY = (num1);
            this.transform.ScaleX = (num1);
            this.transform.TranslateX = 0;
            this.transform.TranslateY = (this.TransfromY);
            this.IsDragHorizontal = true;
        }

        public void DragCompleted(object sender, DragCompletedGestureEventArgs e)
        {
        }

        public void DragDelta(ManipulationDeltaEventArgs e)
        {
            double x = this._oPoint.X;
            Point translation = e.DeltaManipulation.Translation;
            this._oPoint.X = (x + translation.X);
            double y = this._oPoint.Y;
            Point point = e.DeltaManipulation.Translation;
            this._oPoint.Y = (y + point.Y);
            if (this.transform.ScaleX > 1)
            {
                this.transform.TranslateX = (this._oPoint.X);
            }
            if (e.DeltaManipulation.Translation.Y > 0)
            {
                if (this.transform.ScaleY <= 1 && this.transform.TranslateY >= this.TransfromY)
                {
                    this.transform.TranslateY = (this.TransfromY);
                    return;
                }
                this.transform.TranslateY = (this._oPoint.Y);
                return;
            }
            if (this.transform.ScaleY <= 1)
            {
                if (this.DistanceY <= 0)
                {
                    return;
                }
                if (this.transform.TranslateY <= -this.DistanceY)
                {
                    this.transform.TranslateY = (-this.DistanceY);
                    return;
                }
            }
            this.transform.TranslateY = (this._oPoint.Y);
        }

        public void DragStarted()
        {
            this._oPoint = new Point(this.transform.TranslateX, this.transform.TranslateY);
        }

        public static LDBComicChapterImage GetQImage(ImagePlane img)
        {
            return (LDBComicChapterImage)img.GetValue(ImagePlane.ImageProperty);
        }

        private void ImageLoadFailed(string sMsg)
        {
            this.tbLoadingNum.Text = ("");
            this.ErrGrid.Visibility = (System.Windows.Visibility)(0);
            this.tbError.Text = (sMsg);
            this.imgRetry.Source =(new BitmapImage(new Uri("/Assets/Tiles/LogoBig.png", UriKind.RelativeOrAbsolute)));
            this.loading.Visibility = (System.Windows.Visibility)(1);
        }

        private void ImageOpened(object sender, RoutedEventArgs e)
        {
            Image image = sender as Image;
            if (image != null)
            {
                image.Visibility = (System.Windows.Visibility)(0);
            }
        }

        public void InitCtlProperty()
        {
            base.Width = (this._width);
            base.Height = (this._height);
            this.pLoading.Width = (this._width);
            this.LayoutRoot.Width = (this._width);
            this.LayoutRoot.Height = (this._height);
            CompositeTransform compositeTransform = this.transform;
            double num = 1;
            double num1 = num;
            this.transform.ScaleY = (num);
            compositeTransform.ScaleX = (num1);
            this.transform.TranslateX = (0);
            this.transform.TranslateY = (this.TransfromY);
            this.IsDragHorizontal = true;
            this.Mutexes = false;
        }

        private void LoadCompleteEvent(CAsyncImageTask sender, LoadCompleteEventArgs args)
        {
            base.Dispatcher.BeginInvoke(() =>
            {
                try
                {
                    using (Stream memoryStream = new MemoryStream((byte[])args.Data, false))
                    {
                        if (memoryStream.CanSeek)
                        {
                            memoryStream.Seek((long)0, SeekOrigin.Begin);
                        }
                        BitmapImage bitmapImage = new BitmapImage();
                        bitmapImage.CreateOptions = (BitmapCreateOptions)16;
                        bitmapImage.SetSource(memoryStream);
                        this.Photo.Source = (bitmapImage);
                    }
                    this.loading.Visibility = (System.Windows.Visibility)(1);
                }
                catch (Exception exception)
                {
                    this.ImageLoadFailed(exception.Message);
                }
            });
        }

        private void LoadErrorEvent(CAsyncImageTask sender, LoadErrorEventArgs args)
        {
            base.Dispatcher.BeginInvoke(() => this.ImageLoadFailed("网络环境不稳定,点击否重新加载..."));
        }

        private void LoadingImages(object ob)
        {
            LDBComicChapterImage comicImage = ob as LDBComicChapterImage;
            if (comicImage == null || comicImage.ImageUrl == null)
            {
                this.Photo.Source =(null);
                return;
            }
            try
            {
                this.InitCtlProperty();
                //ICache cache = (comicImage.DownTag == 4 ? CacheHelper.ImagelocalCache : CacheHelper.ImageCache);
                ICache cache = CacheHelper.ImageCache;
                this.Photo.Visibility = (System.Windows.Visibility)1;
                this.ErrGrid.Visibility = (System.Windows.Visibility)(1);
                this.loading.Visibility = (System.Windows.Visibility)(0);
                this.tbLoadingNum.Text = ("");
                if (!cache.exist(comicImage.ImageUrl))
                {
                    if (this._tmpTask != null)
                    {
                        this._tmpTask.Dispose();
                    }
                    CAsyncImageTask cAsyncImageTask = new CAsyncImageTask(comicImage.ImageUrl)
                    {
                        Cache = cache
                    };              
                    cAsyncImageTask.LoadProcessEvent += this.LoadProcessEvent;
                    cAsyncImageTask.LoadErrorEvent += this.LoadErrorEvent;
                    cAsyncImageTask.LoadCompleteEvent += this.LoadCompleteEvent;
                    cAsyncImageTask.Start();
                    this._tmpTask = cAsyncImageTask;
                }
                else
                {
                    //byte[] numArray = (byte[])cache.@get(comicImage.ImageUrl);                    
                    //if (numArray != null)
                    //{
                    //    using (Stream memoryStream = new MemoryStream(numArray, false))
                    //    {
                    //        if (memoryStream.CanSeek)
                    //        {
                    //            memoryStream.Seek((long)0, SeekOrigin.Begin);
                    //        }
                    //        BitmapImage bitmapImage = new BitmapImage();
                    //        bitmapImage.SetSource(memoryStream);
                    //        WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapImage);
                    //        this.Photo.Source =(writeableBitmap);
                    //    }
                    //}

                    string filePath = string.Concat(KEYS.ComicIslandCacheDirectory, "/", KEYS.CacheImagePrefix, comicImage.ComicId, "_",
                    comicImage.PartId, "_", MD5.GetMd5String(comicImage.ImageUrl));
                    this.BindImage(filePath, comicImage);
                    this.Photo.Visibility = (System.Windows.Visibility)(0);
                    this.loading.Visibility = (System.Windows.Visibility)(1);
                }
            }
            catch (Exception exception)
            {
            }
        }

        void BindImage(string filePath, LDBComicChapterImage dbImage)
        {
            try
            {
                using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (!IsolatedStorageHelper.Instance.FileExists(filePath))
                    {
                        BitmapImage image = new BitmapImage();
                        image.UriSource = new Uri(dbImage.ImageUrl, UriKind.Absolute);
                    }
                    else
                    {
                        using (IsolatedStorageFileStream isoStream = store.OpenFile(filePath, FileMode.Open))
                        {
                            Stream memoryStream = new MemoryStream();
                            isoStream.CopyTo(memoryStream);

                            isoStream.Close();
                            isoStream.Dispose();
                            store.Dispose();

                            BitmapImage bitmapImage = new BitmapImage();
                            bitmapImage.SetSource(memoryStream);
                            WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapImage);
                            this.Photo.Source = (writeableBitmap);
                            this.Photo.Visibility = System.Windows.Visibility.Visible;
                        }
                    }
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), MethodBase.GetCurrentMethod());
            }
        }

        private void LoadProcessEvent(CAsyncImageTask sender, LoadProcessEventArgs args)
        {
            base.Dispatcher.BeginInvoke(() =>
            {
                int curByteNum = (int)(args.CurByteNum * (long)100 / args.TotalByteNum);
                this.tbLoadingNum.Text = (string.Concat("妖气娘正在努力的装载中 ↖(^ω^)↗ \n", curByteNum, "%"));
            });
        }

        private static void OnImageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ImagePlane imagePlane = d as ImagePlane;
            if (imagePlane == null)
            {
                return;
            }
            imagePlane.LoadingImages(e.NewValue);
        }


        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                //根据PropertyChanged事件的委托类，实现PropertyChanged事件：
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private void PhotoSizeChanged(object sender, EventArgs args)
        {
            SizeChangedEventArgs sizeChangedEventArg = args as SizeChangedEventArgs;
            if (sizeChangedEventArg != null)
            {
                Size size = (sizeChangedEventArg.NewSize.IsEmpty ? sizeChangedEventArg.PreviousSize : sizeChangedEventArg.NewSize);
                if (size.Height < this._height)
                {
                    this.transform.TranslateY = (Math.Abs(size.Height - this._height) / 2);
                    this.TransfromY = this.transform.TranslateY;
                    this.DistanceY = 0;
                    return;
                }
                this.transform.TranslateY = (0);
                this.TransfromY = this.transform.TranslateY;
                this.DistanceY = Math.Abs(size.Height - this._height);
            }
        }

        public void PinchCompleted()
        {
            if (this.transform.ScaleX < 1)
            {
                this.RestSx.To = (new double?(1));
                this.RestSy.To = (new double?(1));
                this.RestS.Begin();
                CompositeTransform compositeTransform = this.transform;
                double num = 1;
                double num1 = num;
                this.transform.ScaleX = (num);
                compositeTransform.ScaleY = (num1);
            }
            else if (this.transform.ScaleX > 2)
            {
                this.RestSx.To = (new double?(2));
                this.RestSy.To = (new double?(2));
                this.RestS.Begin();
                CompositeTransform compositeTransform1 = this.transform;
                double num2 = 2;
                double num3 = num2;
                this.transform.ScaleX = (num2);
                compositeTransform1.ScaleY = (num3);
            }
            this.IsDragHorizontal = this.transform.ScaleX <= 1;
        }

        public void PinchDelta(ManipulationDeltaEventArgs e)
        {
            CompositeTransform compositeTransform = this.transform;
            compositeTransform.ScaleX = (compositeTransform.ScaleX * e.PinchManipulation.DeltaScale);
            CompositeTransform compositeTransform1 = this.transform;
            compositeTransform1.ScaleY = (compositeTransform1.ScaleY * e.PinchManipulation.DeltaScale);
            this.transform.ScaleX = (e.PinchManipulation.CumulativeScale);
            this.transform.ScaleY = (e.PinchManipulation.CumulativeScale);
            e.Handled = (true);
        }

        public void PinchStarted()
        {
            this.RestS.Stop();
        }

        public bool ScrollImagePage(ComicIsland.Common.Helper.ScrollPageModel scrollPage)
        {
            double distanceY;
            this.Mutexes = true;
            double num = 0;
            switch (scrollPage)
            {
                case ComicIsland.Common.Helper.ScrollPageModel.ScrollUp:
                    {
                        if (this.transform.ScaleY <= 1)
                        {
                            distanceY = this.DistanceY - Math.Abs(this.transform.TranslateY);
                        }
                        else
                        {
                            double distanceY1 = this.DistanceY + (this.transform.ScaleY - 1) * this.Photo.ActualHeight / 2;
                            distanceY = distanceY1 - Math.Abs(this.transform.TranslateY);
                        }
                        if (distanceY <= 0)
                        {
                            return false;
                        }
                        num = (distanceY > this._height ? this.transform.TranslateY - this._height : this.transform.TranslateY - distanceY);
                        break;
                    }
                case ComicIsland.Common.Helper.ScrollPageModel.ScrollDown:
                    {
                        distanceY = (this.transform.ScaleY <= 1 ? 0 : (this.transform.ScaleY - 1) * this.Photo.ActualHeight / 2);
                        if (this.transform.TranslateY.Equals(distanceY))
                        {
                            return false;
                        }
                        num = (Math.Abs(this.transform.TranslateY) > this._height ? this.transform.TranslateY + this._height : distanceY);
                        break;
                    }
            }
            this.Animy.To = (new double?(num));
            this.Story.Begin();
            return true;
        }

        public static void SetQImage(ImagePlane img, LDBComicChapterImage value)
        {
            img.SetValue(ImagePlane.ImageProperty, value);
        }

        private void Story_OnCompleted(object sender, EventArgs e)
        {
            this.Mutexes = false;
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
